library api;

import 'package:dio/dio.dart';
import 'package:get/get.dart' hide Response, FormData;
import 'package:get/get_connect/http/src/status/http_status.dart';
import 'package:nanoid/async.dart';
import 'package:work_tools/generated/json/base/json_convert_content.dart';
import 'package:work_tools/model/response_entity.dart';
import 'package:work_tools/model/token_entity.dart';
import 'package:work_tools/utils/cache_util.dart';
export 'package:work_tools/dio/api.dart';

part 'api/common.dart';
part 'api/auth.dart';

Dio get dio => Get.find();

API get api => Get.find();

class API {
  Future<T?> get<T>(
      path, {
        Map<String, dynamic>? data,
        String? loadingMsg,
        bool isMock = false,
        bool needThrow = false,
        bool needToast = true,
      }) async {
    final requestId = await nanoid();
    final needLoading = loadingMsg != null && loadingMsg.isNotEmpty;
    Response? dioResponse;
    try {
      dioResponse = await dio.get(path, queryParameters: data);
    } catch (e) {
      if (needThrow) rethrow;
      return null;
    }
    try {
      final result = await analyseResponse<T>(path, requestId,
        data: data,
        loadingMsg: loadingMsg,
        dioResponse: dioResponse,
        needThrow: needThrow,
        needToast: needToast,
      );
      return result;
    } catch (e) {
      if (needThrow) rethrow;
      return null;
    }
  }

  Future<T?> post<T>(
      path, {
        data,
        String? loadingMsg,
        bool isMock = false,
        bool needThrow = false,
        bool needToast = true,
      }) async {
    final requestId = await nanoid();
    final needLoading = loadingMsg != null && loadingMsg.isNotEmpty;
    if (needLoading) {
    }
    Response? dioResponse;
    try {
      dioResponse = await dio.post(path, data: data);
    } catch (e) {
      if (needThrow) rethrow;
      return null;
    }
    try {
      final result = await analyseResponse<T>(path, requestId,
        data: data,
        loadingMsg: loadingMsg,
        dioResponse: dioResponse,
        needThrow: needThrow,
        needToast: needToast,
      );
      return result;
    } catch (e) {
      if (needThrow) rethrow;
      return null;
    }
  }

  Future<T?> analyseResponse<T>(
      String path,
      String requestId, {
        dynamic data,
        Response? dioResponse,
        String? loadingMsg,
        bool needThrow = false,
        bool needToast = true,
      }) async {
    if (dioResponse == null || dioResponse.statusCode != HttpStatus.ok) {
      throw Error();
    }

    ResponseEntity? res = jsonConvert.convert<ResponseEntity>(dioResponse.data);
    if (res?.code == 203) {
      throw Error();
    } else if (res?.code == 0) {
      return await Future.value(JsonConvert.fromJsonAsT<T>(res?.data));
    } else {
      throw Error();
    }
  }
}
